<?php
/**
 * Created by PhpStorm.
 * User: xuke
 * Date: 16/5/19
 * Time: 下午3:40
 */
namespace App\Http\Controllers\Test;

use App\Http\Controllers\BaseController;
use Illuminate\Support\Facades\Redis;
use App\Logic\UserLogic;
use App\Http\Model\Users AS UserModel;
use WechatFacade;
class TestController extends BaseController
{
    public function index()
    {
        $result = WechatFacade::getAccessToken();
        print_r($result);

    }

    public function test()
    {
        Redis::set('name', 'Taylor');
        echo Redis::get('name');
    }

    public function testRedis()
    {
        Redis::set('num', 0);
        Redis::set('total', 0);
        Redis::set('total2', 0);
        echo Redis::get('total');
        for ($i = 0; $i < 50; $i++)
        {
            $urls[] = 'http://edwin.laravel.cn/test/redis';
        }
        $this->rolling_curl($urls, 5);
//        $this->muiti_curl($urls);
        $marked = Redis::get('num');
        $total = Redis::get('total');
        $total2 = Redis::get('total2');
        echo $marked;
        echo '|'.$total;
        echo '|'.$total2;
    }

    public function showTotal()
    {
        echo Redis::get('total');
    }

    public function redis()
    {

        Redis::incrBy('total2', 1);
        if ($this->tryGetLock())
        {
            $this->doRedis();
        }else {
            $iswhile = true;
            while($iswhile)
            {
                $isLock = $this->tryGetLock();
                if ($isLock)  //如果获取到锁
                {
                    $this->doRedis();
                    $iswhile = false;
                }

            }
        }

    }

    /**
     * 有锁资源的执行保存redis数据的操作
     */
    private function doRedis()
    {
        $marked = Redis::get('num');
        $total = Redis::get('total');
        $total += 1;
        if ($marked == 0)
        {
            //            sleep(2);
            UserLogic::create()->save(['username' => 'test']);
            $marked += 1;
            Redis::set('num', $marked);
        }
        Redis::incrBy('total', 1);
        Redis::del('ok');
    }

    /**
     * 尝试获取锁资源
     * return bool
     */
    private function tryGetLock()
    {
        $overtime = time() + 60;
        $ok = Redis::setNX('ok', $overtime);
        if ($ok || (time() > Redis::get('ok') && time() > Redis::GETSET('ok', $overtime)))
        {
            return true; //获得了锁资源
        }else{
            return false;
        }
    }

    private function rolling_curl($urls, $delay) {
        $queue = curl_multi_init();
        $map = array();

        foreach ($urls as $url) {
            $ch = curl_init();

            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_TIMEOUT, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_NOSIGNAL, true);

            curl_multi_add_handle($queue, $ch);
            $map[(string) $ch] = $url;
        }

        $responses = array();
        do {
            while (($code = curl_multi_exec($queue, $active)) == CURLM_CALL_MULTI_PERFORM) ;

            if ($code != CURLM_OK) { break; }

            // a request was just completed -- find out which one
            while ($done = curl_multi_info_read($queue)) {

                // get the info and content returned on the request
//                $info = curl_getinfo($done['handle']);
//                $error = curl_error($done['handle']);
//                $results = callback(curl_multi_getcontent($done['handle']), $delay);
//                $responses[$map[(string) $done['handle']]] = compact('info', 'error', 'results');
//
//                // remove the curl handle that just completed
//                curl_multi_remove_handle($queue, $done['handle']);
//                curl_close($done['handle']);
            }

            // Block for data in / output; error handling is done by curl_multi_exec
            if ($active > 0) {
                curl_multi_select($queue, 0.5);
            }

        } while ($active);

        curl_multi_close($queue);
        return $responses;
    }

    private function muiti_curl($urls)
    {
        $mh = curl_multi_init();
        foreach ($urls as $i => $url) {
            $conn[$i]=curl_init($url);
            curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);
            curl_multi_add_handle ($mh,$conn[$i]);
        }

//        do {
//            $mrc = curl_multi_exec($mh,$active);
//        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
//        while ($active and $mrc == CURLM_OK) {
//            if (curl_multi_select($mh) != -1) {
//                do {
//                    $mrc = curl_multi_exec($mh, $active);
//                } while ($mrc == CURLM_CALL_MULTI_PERFORM);
//            }
//        }

        do { $n=curl_multi_exec($mh,$active); } while ($active);
        foreach ($urls as $i => $url) {
            $res[$i]=curl_multi_getcontent($conn[$i]);
            curl_close($conn[$i]);
        }
    }

    /**
     * 测试添加到不同的数据库中
     */
    public function muiltDataBaseAdd()
    {
        $userModel = new UserModel();
        $saveData = [
            'username' => 'test'
        ];
        $userModel->setConnection('mysql')->fill($saveData)->save();
        $userModel2 = new UserModel();
        $userModel2->setConnection('mysql2')->fill($saveData)->save();
    }
}